package com.netty.server.config;

import com.netty.server.base.DefaultConnectionGroup;
import com.netty.server.base.RequestRegister;
import com.netty.server.base.TankEnvironment;
import com.netty.server.base.TankServer;
import com.netty.server.processor.DefaultDownProcessor;
import com.netty.server.processor.DefaultUpProcessor;
import com.netty.server.processor.DownProcessor;
import com.netty.server.processor.UpProcessor;
import com.netty.server.processor.down.DownPlugin;
import com.netty.server.processor.up.LoginPlugin;
import com.netty.server.processor.up.UpPlugin;
import com.netty.server.sender.CmdSender;
import com.netty.server.sender.DefaultCmdSender;
import com.netty.server.utils.CmdIdGenerator;
import io.netty.channel.nio.NioEventLoopGroup;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;

@Configuration
@EnableConfigurationProperties({TankProperties.class})
public class TankConfig {

    @Bean(initMethod = "init", destroyMethod = "release")
    public TankServer tankServer(TankEnvironment environment) {
        return new TankServer(environment);
    }

    @Bean(destroyMethod = "release")
    public TankEnvironment tankEnvironment(TankProperties properties, UpProcessor upProcessor, DownProcessor downProcessor) {
        return TankEnvironment.builder()
                .bossGroup(new NioEventLoopGroup(properties.getConnectThreadCount()))
                .workGroup(new NioEventLoopGroup(properties.getIoThreadCount()))
                .tankParams(properties)
                .cmdIdGenerator(new CmdIdGenerator())
                .register(new RequestRegister(new NioEventLoopGroup(properties.getRequestThreadCount())))
                .connectionGroup(new DefaultConnectionGroup())
                .upProcessor(upProcessor)
                .downProcessor(downProcessor)
                .build();
    }

    @Bean
    public UpProcessor upProcessor(LoginPlugin loginPlugin, List<? extends UpPlugin<?>> upPlugins) {
        return new DefaultUpProcessor(loginPlugin, upPlugins);
    }

    @Bean
    public DownProcessor downProcessor(List<? extends DownPlugin> downPlugins) {
        return new DefaultDownProcessor(downPlugins);
    }

    @Bean
    public CmdSender cmdSender(TankEnvironment environment) {
        return new DefaultCmdSender(environment.getConnectionGroup());
    }

}
